package com.ruiao.car.config;
import com.ruiao.car.constant.Constant;
import com.ruiao.car.dto.AccountDto;
import com.ruiao.car.enums.ResultEnum;
import com.ruiao.car.service.IAccountService;
import com.ruiao.car.service.RedisService;
import com.ruiao.car.utils.AccountThreadLocal;
import com.ruiao.car.utils.HeaderUtil;
import com.ruiao.car.utils.annotation.RequiresPermissions;
import com.ruiao.car.utils.AccountHeaderUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 登录拦截器
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private IAccountService accountService;
    
    @Autowired
	private RedisService redisService;


    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HeaderUtil headerUtil = HeaderUtil.parseRequestToHeader(request);

        AccountHeaderUtil userHeaderUtil = new AccountHeaderUtil(headerUtil);

        String token = headerUtil.getToken();
        AccountDto account = null;

        if (!StringUtils.isEmpty(token)) {
        	Long userId = redisService.get(Constant.TOKEN + token.toString(),Long.class);
            account = accountService.selectAccountByToken(userId);
            userHeaderUtil.setAccount(account);
        }


        //把auth和user信息放入ThreadLocal中
        AccountThreadLocal.set(userHeaderUtil);

        final HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        boolean isLogin = method.isAnnotationPresent(RequiresPermissions.class);

        //NoSign noSignAnnotation = method.getAnnotation(NoSign.class);

        //注解必须登录，未登录情况下返回未登录错误
        if (isLogin && account == null) {
            throw new BusinessException(ResultEnum.NO_LOGIN);
        }

        /** 校验签名 **/
       /* if( account != null ){
            LoginInterceptorUtil.checkSign(noSignAnnotation,request,headerUtil,account.getSecretKey());
        }*/

        return true;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        AccountThreadLocal.remove();
    }
}